<?php

namespace App\Http\Controllers\Backstage\System;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use App\Services\PartnerGroupTypeService;
use App\Services\PartnerGroupTypePermissionService;
use App\Services\MenuPermissionService;
use App\PartnerGroupType;
use App\PartnerGroupTypePermission;
use App\MenuPermission;
use App\UserGroup;

class PartnerGroupTypeController extends Controller
{
    private $partnerGroupTypeService = null;
    private $menuPermissionService = null;
    private $partnerGroupTypePermissionService = null;

    public function __construct(PartnerGroupTypeService $partnerGroupTypeService,
        PartnerGroupTypePermissionService $partnerGroupTypePermissionService,
        MenuPermissionService $menuPermissionService)
    {
        $this->partnerGroupTypeService = $partnerGroupTypeService;
        $this->partnerGroupTypePermissionService = $partnerGroupTypePermissionService;
        $this->menuPermissionService = $menuPermissionService;
    }

    public function index()
    {
        return view('backstage.system.partnergrouptype.grouptype');
    }

    public function getPartnerGroupTypes(Request $request)
    {
        return $this->partnerGroupTypeService
            ->getPartnerGroupTypes($request->all());
    }

    public function create()
    {
        return view('backstage.system.partnergrouptype.create');
    }

    public function saveNew(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNew($input);

        PartnerGroupType::create($input);

        return response()->json([
            'Success' => true,
            'Message' => '新增合作伙伴类型成功',
        ]);
    }

    public function edit($typeId)
    {
        $partnerGroupType = PartnerGroupType::findOrFail($typeId);
        return view('backstage.system.partnergrouptype.create', [
            'partnerGroupType' => $partnerGroupType
        ]);
    }

    public function update(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdate($input);

        $partnerGroupType = PartnerGroupType::findOrFail($input['id']);
        $partnerGroupType->update($input);

        return response()->json([
            'Success' => true,
            'Message' => '保存合作伙伴类型成功',
        ]);
    }

    public function delete(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDelete($input);

        $partnerGroupType = PartnerGroupType::findOrFail($input['id']);
        $partnerGroupType->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除合作伙伴类型成功',
        ]);
    }

    public function getPermissionsByType($typeId)
    {
        $menuPermissions = $this->menuPermissionService->getCascadeMenuPermissionByLevel(4);

        $partnerGroupTypePerms = $this->partnerGroupTypePermissionService->getPermissionByPartnerGroupType($typeId);

        return view('backstage.system.partnergrouptype.permission', [
            'groupTypeId' => $typeId,
            'menuPermissions' => $menuPermissions,
            'currentPermssionIds' => $partnerGroupTypePerms->pluck('permission_id')->toArray()
        ]);
    }

    public function saveGroupTypePermissions(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSavePermission($input);

        $permissionIds = explode(',', $input['perms']);

        $this->partnerGroupTypePermissionService->setPartnerGroupTypePermissions($input['typeId'], $permissionIds);

        return response()->json([
            'Success' => true,
            'Message' => '保存权限成功',
        ]);
    }

    private function validateWhenSavePermission(Array $input)
    {
        return Validator::make($input, [
                'typeId' => 'required|exists:partner_group_types,id'
            ], [
                'typeId.required' => '必须传入合作伙伴类型ID',
                'typeId.exists' => '该合作伙伴类型ID参数有误，合作伙伴类型不存在'
            ])->after(function ($validator) use($input) {
                if ($input['perms'] !== '') {
                    $permissionIds = explode(',', $input['perms']);
                    $allPermissions = collect($this->menuPermissionService->getMenuPermissions([], [
                        MenuPermission::$PERMISSION_TYPE_TOP_NAVI,
                        MenuPermission::$PERMISSION_TYPE_MENU_GROUP,
                        MenuPermission::$PERMISSION_TYPE_MENU,
                        MenuPermission::$PERMISSION_TYPE_OPERATION
                    ], false))->pluck('id')->toArray();

                    $defaultPermission = $this->menuPermissionService->getDefaultMenuPermission();

                    if (empty($defaultPermission)) {
                        $validator->errors()->add('perms.no_default', '系统尚未设置默认菜单，不可继续');
                    } else {
                        $illegalPermission = true;
                        $hasSetDefault = false;
                        foreach ($permissionIds as $permissionId) {
                            if (!empty($permissionId)) {
                                $illegalPermission = $illegalPermission && in_array($permissionId, $allPermissions);
                                $hasSetDefault = $hasSetDefault || ($permissionId == $defaultPermission->id);
                            }
                        }

                        if (!$illegalPermission) {
                            $validator->errors()->add('perms.illegal', '传入的权限ID里有不合法的数据');
                        }

                        if (!$hasSetDefault) {
                            $validator->errors()->add('perms.has_default', '没有设置默认菜单，会导致无法正常访问');
                        }
                    }

                } else {
                    $validator->errors()->add('perms.required', '至少要选择一个权限');
                }
            }
        )->validate();
    }

    private function validateWhenSaveNew(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('partner_group_types')->where(function ($query) use($input) {
                    //同一种原始类型下，名称不可相同
                    $query->where('name', $input['name'])
                        ->where('group_type', $input['group_type']);
                })
            ],
            'group_type' => [
                'required',
                Rule::in([UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE, UserGroup::$GROUP_TYPE_USER])
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenSaveNew())->validate();
    }

    private function getValidateMessagesWhenSaveNew()
    {
        return [
            'name.required' => '合作伙伴类型名称必须存在',
            'name.max'  => '合作伙伴类型名称长度不可超过:max',
            'name.unique' => '当前原始用户组类别下已经存在该合作伙伴类型名称',
            'group_type.required' => '必须指定一个原始用户组类别',
            'group_type.in'  => '原始用户组类别不正确，只能为外部合作单位或者个人，不可为主运营单位或者下属部门机构',
            'sort_order.required' => '排序号必须存在',
            'sort_order.numeric' => '排序号必须是数字',
        ];
    }

    private function validateWhenSaveUpdate(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('partner_group_types')->where(function ($query) use($input) {
                    //同一种原始类型下，名称不可相同
                    $query->where('name', $input['name'])
                        ->where('group_type', $input['group_type'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'group_type' => [
                'required',
                Rule::in([UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE, UserGroup::$GROUP_TYPE_USER])
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenSaveUpdate())->validate();
    }

    private function getValidateMessagesWhenSaveUpdate()
    {
        return [
            'name.required' => '合作伙伴类型名称必须存在',
            'name.max'  => '合作伙伴类型名称长度不可超过:max',
            'name.unique' => '当前原始用户组类别下已经存在该合作伙伴类型名称',
            'group_type.required' => '必须指定一个原始用户组类别',
            'group_type.in'  => '原始用户组类别不正确，只能为外部合作单位或者个人，不可为主运营单位或者下属部门机构',
            'sort_order.required' => '排序号必须存在',
            'sort_order.numeric' => '排序号必须是数字',
        ];
    }

    private function validateWhenDelete(Array $input)
    {
        return Validator::make($input, [
                'id' => 'required|exists:partner_group_types,id'
            ], [
                'id.required' => '必须传入合作伙伴类型ID',
                'id.exists' => '该合作伙伴类型ID参数有误，合作伙伴类型不存在'
            ])->after(function ($validator) use($input) {
                if ($this->partnerGroupTypeService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '已经有单位属于该合作伙伴类型，不可删除该类型');
                }
            })->validate();
    }
}
